<!-- eslint-disable vue/valid-v-model -->
<template>
  <Form
    ref="formRef"
    v-slot="{ values }"
    :initial-values="generateDefaultValues(formSchema)"
    @submit="onSubmit"
  >
    <!-- 正常渲染 -->
    <div
      v-for="{
        name,
        label,
        rules,
        type,
        placeholder,
        ...attrs
      } in formSchema.fields"
      :key="name"
      class="form-field flex items-center gap-2"
    >
      <div v-if="!isObject(values[name])" class="flex items-center gap-2">
        <FormLabel :label="label" :name="name" />
        <FormnormalRendering
          :attrs="attrs"
          :name="name"
          :placeholder="placeholder ?? ''"
          :rules="rules!"
          :type="type ?? ''"
        />
        <!-- 错误信息 -->
        <FormErrorMessage :modelkey="name" />
      </div>
      <!-- 对象 -->
      <div v-else class="flex items-center gap-2">
        <FormLabel :label="label" name="" />
        <template v-for="(key, index) in Object.keys(values[name])" :key="key">
          <Formobject
            :attrs="attrs"
            :index="index"
            :username-key="key"
            :values="values"
          />
        </template>
      </div>
    </div>

    <!-- 按钮组 -->
    <div class="flex gap-4">
      <button
        class="flex-1 rounded-md bg-blue-500 px-4 py-2 text-white hover:bg-blue-600 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2"
        type="submit"
      >
        提交表单
      </button>
      <button
        class="flex-1 rounded-md bg-green-500 px-4 py-2 text-white hover:bg-green-600 focus:outline-none focus:ring-2 focus:ring-green-500 focus:ring-offset-2"
        type="button"
        @click="setValues"
      >
        设置值
      </button>
      <button
        class="flex-1 rounded-md bg-gray-500 px-4 py-2 text-white hover:bg-gray-600 focus:outline-none focus:ring-2 focus:ring-gray-500 focus:ring-offset-2"
        type="button"
        @click="resetForm"
      >
        重置表单
      </button>
    </div>
  </Form>
</template>
<script setup lang="tsx">
import { ref } from 'vue';

import { isObject } from '@vben/utils';

import { toTypedSchema } from '@vee-validate/zod';
import { ElMessage } from 'element-plus';
import { Form, type FormContext } from 'vee-validate';
import z from 'zod';

import {
  FormErrorMessage,
  FormLabel,
  FormnormalRendering,
  Formobject,
} from './components/index';

import 'animate.css';

const formRef = ref<FormContext | null>();
const onSubmit = (_values: any, { resetForm }: any) => {
  // 表单验证通过后的处理逻辑
  ElMessage.success(`提交成功 ${JSON.stringify(_values)}`);
  // 方法1: 使用 FormActions 对象重置表单（推荐）
  resetForm();
};

// 设置值`
const setValues = () => {
  if (formRef.value) {
    formRef.value.setValues({
      email: 'ummm@example.com',
      password: 'P@$$w0Rd',
      username: {
        value: '123',
        label: '123',
      },
      age: 20,
      confirmPassword: '123456',
      gender: '男',
      name: '张三',
    });
    // 表单已重置
  } else {
    // 表单实例未找到
  }
};

// 重置表单
const resetForm = () => {
  if (formRef.value) {
    // 使用 handleReset 方法，这是官方推荐的方式
    formRef.value.resetForm({
      values: {
        name: '',
        email: '',
        username: {
          value: '',
          label: '',
        },
        password: '',
        confirmPassword: '',
        age: '',
      },
    });
  }
};
const valueValidationRules = toTypedSchema(
  z.string().min(1, { message: 'value 不能为空' }),
);
const labelValidationRules = toTypedSchema(
  z.string().min(1, { message: 'label 不能为空' }),
);
// 定义表单验证模式
const formSchema = {
  fields: [
    {
      label: '用户名',
      name: 'username',
      placeholder: '请输入用户名',
      defaultValue: {
        value: '123',
        label: '123',
      },
      rulesArr: [valueValidationRules, labelValidationRules],
      components: ['ElButton', 'ElInput'],
    },
    {
      label: '性别',
      name: 'gender',
      component: 'ElRadio',
      defaultValue: '男',
      componentProps: {
        options: [
          { label: '男', value: '男' },
          { label: '女', value: '女' },
        ],
      },
      placeholder: '请选择性别',
      rules: toTypedSchema(z.string().min(1, { message: '请选择性别' })),
    },
    {
      label: '姓名',
      name: 'name',
      component: 'ElButton',
      placeholder: '请输入您的姓名',
      rules: toTypedSchema(
        z
          .string({
            message: '姓名至少需要2个字符',
          })
          .min(2, { message: '姓名至少需要2个字符' }),
      ),
    },
    {
      label: '邮箱',
      name: 'email',
      component: 'ElInput',

      type: 'email',
      placeholder: '请输入您的邮箱',
      rules: toTypedSchema(
        z
          .string({
            message: '请输入有效的邮箱地址',
          })
          .email({ message: '请输入有效的邮箱地址' }),
      ),
    },
    {
      label: '确认密码',
      name: 'confirmPassword',
      as: 'input',
      type: 'password',
      placeholder: '请再次输入密码',
      rules: toTypedSchema(z.string().min(1, { message: '请确认密码' })),
    },
    {
      label: '年龄',
      name: 'age',
      as: 'input',
      type: 'number',
      placeholder: '请输入年龄',
    },
  ],
};

// // // 初始值
// const initialValues = {
//   gender: '男',
//   name: '张三',
//   username: {
//     value: '12312121',
//     label: '123',
//   },
//   email: 'zhangsan@example.com',
//   password: '123456',
//   confirmPassword: '123456',
//   age: 20,
// };

function generateDefaultValues(formSchema: any) {
  const defaultValues: any = {};

  if (!formSchema?.fields || !Array.isArray(formSchema.fields)) {
    return defaultValues;
  }

  formSchema.fields.forEach((field: any) => {
    const { name, defaultValue } = field;

    // 如果字段明确指定了默认值，优先使用
    defaultValues[name as keyof typeof defaultValues] =
      defaultValue === undefined ? '' : defaultValue;
  });

  return defaultValues;
}
</script>

<style scoped>
.form-field {
  margin-bottom: 1rem;
}
</style>
